package com.gitee.wsl.ext.number

/*fun String.parseInt(): Int = when {
    this.startsWith("0x", ignoreCase = true) -> this.substring(2).toLong(16).toInt()
    this.startsWith("0o", ignoreCase = true) -> this.substring(2).toLong(8).toInt()
    this.startsWith("0b", ignoreCase = true) -> this.substring(2).toLong(2).toInt()
    else -> this.toInt()
}*/


internal const val BIN_RADIX = 2
internal const val HEX_RADIX = 16
internal const val OCT_RADIX = 8
private val prefixRegex = "(?<=0[box])".toRegex()

fun String.parseLong(): Long {
    val value = replace("_", "").split(prefixRegex, limit = 2)

    return if (value.size == 2) {
        val (prefix, digits) = value
        when (prefix) {
            "0b" -> digits.toLong(BIN_RADIX)
            "0o" -> digits.toLong(OCT_RADIX)
            "0x" -> digits.toLong(HEX_RADIX)
            else -> throw Exception("Invalid radix prefix for Long number <$this> $prefix: expected \"0b\", \"0o\", or \"0x\".")
        }
    } else {
        value.first().toLong()
    }
}

fun String.parseInt(): Int {
    val value = replace("_", "").split(prefixRegex, limit = 2)

    return if (value.size == 2) {
        val (prefix, digits) = value
        when (prefix) {
            "0b" -> digits.toInt(BIN_RADIX)
            "0o" -> digits.toInt(OCT_RADIX)
            "0x" -> digits.toInt(HEX_RADIX)
            else -> throw Exception("Invalid radix prefix for Long number <$this> $prefix: expected \"0b\", \"0o\", or \"0x\".")
        }
    } else {
        value.first().toInt()
    }
}
